/*
 * Created on 10.07.2006 by leck
 *
 */
package de.devisnik.eidle;

import de.devisnik.eidle.screen.IScreen;

public abstract class AbstractScreenToggler {

	private final IScreen[] itsScreens;

	private final IScreenHandler itsScreenHandler;

	public AbstractScreenToggler(final IScreen[] screens,
			final IScreenHandler handler) {
		itsScreens = screens;
		itsScreenHandler = handler;
	}

	public IScreen getActiveScreen() {
		return itsScreenHandler.getCurrent();
	}
	public void nextScreen() {
		final IScreen nextScreen = findNextEnabled();
		if (nextScreen == null) {
			throw new IllegalStateException("no valid screen");
		}
		itsScreenHandler.activate(nextScreen);
	}

	private IScreen findNextEnabled() {
		IScreen nextScreen = findNextScreen(itsScreenHandler.getCurrent());
		int invalidScreensCount = 0;
		while (!isScreenEnabled(nextScreen)
				&& invalidScreensCount < itsScreens.length) {

			EidleActivator.getDefault().log(
					nextScreen.getClass().getName() + " is disabled!");
			invalidScreensCount++;
			nextScreen = findNextScreen(nextScreen);
		}
		if (invalidScreensCount == itsScreens.length) {
			return null;
		}
		return nextScreen;
	}

	public void dispose() {
		itsScreenHandler.dispose();
		for (int i = 0; i < itsScreens.length; i++) {
			itsScreens[i].dispose();
		}
	}

	private IScreen findNextScreen(final IScreen activeScreen) {
		if (activeScreen == null) {
			return itsScreens[0];
		}
		for (int i = 0; i < itsScreens.length; i++) {
			final IScreen screen = itsScreens[i];
			if (screen == activeScreen) {
				final IScreen nextScreen = itsScreens[(i + 1)
						% itsScreens.length];
				return nextScreen;
			}
		}
		return null;
	}

	private IScreen findPreviousScreen(final IScreen activeScreen) {
		if (activeScreen == null) {
			return itsScreens[itsScreens.length - 1];
		}
		for (int i = 0; i < itsScreens.length; i++) {
			final IScreen screen = itsScreens[i];
			if (screen == activeScreen) {
				final IScreen previousScreen = itsScreens[(i
						+ itsScreens.length - 1)
						% itsScreens.length];
				return previousScreen;
			}
		}
		return null;
	}

	public void previousScreen() {
		final IScreen previousScreen = findPreviousEnabled();
		if (previousScreen == null) {
			throw new IllegalStateException("no valid screen");
		}
		itsScreenHandler.activate(previousScreen);

	}

	private IScreen findPreviousEnabled() {
		IScreen previousScreen = findPreviousScreen(itsScreenHandler
				.getCurrent());
		int invalidScreensCount = 0;
		while (!isScreenEnabled(previousScreen)
				&& invalidScreensCount < itsScreens.length) {
			EidleActivator.getDefault().log(
					previousScreen.getClass().getName() + " is disabled!");
			invalidScreensCount++;
			previousScreen = findPreviousScreen(previousScreen);
		}
		if (invalidScreensCount == itsScreens.length) {
			return null;
		}
		return previousScreen;
	}

	public boolean isLast() {
		final IScreen nextScreen = findNextEnabled();
		final IScreen currentScreen = itsScreenHandler.getCurrent();
		for (int i = 0; i < itsScreens.length; i++) {
			final IScreen screen = itsScreens[i];
			if (screen == nextScreen) {
				return true;
			}
			if (screen == currentScreen) {
				return false;
			}
		}
		throw new IllegalStateException();
	}

	protected abstract boolean isScreenEnabled(final IScreen screen);

}